package com.fjec.market.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjec.common.Const;
import com.fjec.common.enums.EnumSysCode;
import com.fjec.common.exception.BizException;
import com.fjec.common.protocol.JsonResult;
import com.fjec.common.shiro.AccountInfo;
import com.fjec.common.util.DateUtil;
import com.fjec.common.view.AnnexBizItem;
import com.fjec.market.entity.BizMarketBusi;
import com.fjec.market.entity.InfoPurchase;
import com.fjec.market.es.document.PurchaseDocument;
import com.fjec.market.es.repository.PurchaseRepository;
import com.fjec.market.feign.BaseClient;
import com.fjec.market.feign.UserClient;
import com.fjec.market.mapper.InfoPurchaseMapper;
import com.fjec.market.rabbitmq.provider.ShopNumProvider;
import com.fjec.market.service.IBizMarketBusiService;
import com.fjec.market.service.IInfoPersonalService;
import com.fjec.market.service.IInfoPurchaseService;
import com.google.common.base.Functions;
import com.google.common.collect.Lists;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 006.采购商表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2020-09-07
 */
@Service
@Transactional
public class InfoPurchaseServiceImpl extends ServiceImpl<InfoPurchaseMapper, InfoPurchase> implements IInfoPurchaseService {

    @Resource
    private InfoPurchaseMapper mapper;

    @Resource
    private PurchaseRepository purchaseRepository;

    @Resource
    private IBizMarketBusiService bizMarketBusiService;

    @Resource
    private UserClient userClient;

    @Autowired
    private BaseClient baseClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Resource
    private ShopNumProvider shopNumProvider;

    @Resource
    private IInfoPersonalService personalService;

    @Override
    public List<InfoPurchase> getInfoPurchaseByMarkCode(Integer markCode, Page page) {
        return mapper.getInfoPurchaseByMarkCode(markCode, page);
    }

    @Override
    public List<InfoPurchase> getPurchasesByPurchaseIdsAndMarkCode(int markCode, List<Long> purchaseIds, Page page) {
        return mapper.getPurchasesByPurchaseIdsAndMarkCode(markCode, purchaseIds, page);
    }

    @Override
    public Map<String, Object> getPurchaseByUserId(Long userId) {
        InfoPurchase infoPurchase = this.getOne(new QueryWrapper<InfoPurchase>().eq("UserId", userId));
        Map<String, Object> m = infoPurchase.toMap();

        List<BizMarketBusi> markets = bizMarketBusiService.list(new QueryWrapper<BizMarketBusi>().eq("BusiId", infoPurchase.getId()));
        List<Integer> markCodes = markets.stream().map(BizMarketBusi::getMarkCode).collect(Collectors.toList());
        m.put("markCodes", markCodes.stream().map(Functions.toStringFunction()).collect(Collectors.toList()));
        String shopNum = MapUtils.getString(m, "shopNum");
        String shopNumStr = shopNum.substring(0, 2) + "-" + shopNum.substring(2);
        m.put("shopNum", shopNumStr);
        return m;
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public JsonResult  savePurchase(InfoPurchase purchase, String markCodes, Long picId, Long headPicId, Object verifyCode) {
        if (purchase.getId() == null) {
            String phone = purchase.getPhone();
            // check verify code
            String cachedVerifyCodeKey = Const.FJEC_SMS_VERIFY_CODE_KEY + phone;
            Object cachedVerifyCode = redisTemplate.opsForValue().get(cachedVerifyCodeKey);
            if (verifyCode == null || !Objects.equals(cachedVerifyCode, verifyCode)) {
                return JsonResult.failure()
                        .code(EnumSysCode.ERR_3009.getCode())
                        .message(EnumSysCode.ERR_3009.getMsg())
                        .build();
            }
            // check phone exists
            if (userClient.existsPhone(phone)) {
                return JsonResult.failure()
                        .code(EnumSysCode.ERR_3014.getCode())
                        .message(EnumSysCode.ERR_3014.getMsg())
                        .build();
            }
            // 已经注册过的用户不允许再注册
            if (AccountInfo.getBusiType() != 1)
                return JsonResult.failure()
                        .code(EnumSysCode.ERR_3013.getCode())
                        .message(EnumSysCode.ERR_3013.getMsg())
                        .build();
            // 检查简称是否存在
            String name = purchase.getShortName();
            int exist = this.count(new QueryWrapper<InfoPurchase>().eq("ShortName", name));
            if (exist != 0) {
                return JsonResult.failure()
                        .code(EnumSysCode.ERR_3011.getCode())
                        .message(EnumSysCode.ERR_3011.getMsg())
                        .build();
            }
            // save purchase
            purchase.setShopNum(0L);
            purchase.setDepoStatus(0);
            purchase.setShopStar(0);
            purchase.setWeight(0);
            purchase.setAllowPhone(1);
            purchase.setRegStatus(1);
            purchase.setCreateTime(DateUtil.nowLdt());
            this.save(purchase);
            // 更新InfoPersonal busiType用于统计
            personalService.updateBusiTypeByUserId(purchase.getUserId(), 6);
            // save to es
            purchaseRepository.save(new PurchaseDocument(purchase.getId(), AccountInfo.getUserId(), purchase.getShortName()));
            // rpc set annex enable
            List<AnnexBizItem> annexBizItems = new ArrayList<>();
            if (picId != null && picId != 0L) {
                // 营业执照
                AnnexBizItem bizItem = new AnnexBizItem();
                bizItem.setAnnexId(Long.valueOf(picId));
                bizItem.setBizId(purchase.getId());
                bizItem.setBizType(101);
                annexBizItems.add(bizItem);
            }
            baseClient.enableAnnexStatus(annexBizItems);
            // RPC更新用户信息
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("userId", purchase.getUserId());
            dataMap.put("roleCode", "Purchasing");
            dataMap.put("phone", phone);
            int result = userClient.updateUserInfoForCreateShop(dataMap);
            if (result == -1) {
                throw new BizException(EnumSysCode.FAILURE.getCode(), EnumSysCode.FAILURE.getMsg());
            } else if (result == 3014) {
                throw new BizException(EnumSysCode.ERR_3014.getCode(), EnumSysCode.ERR_3014.getMsg());
            }
            // send to mq for generate shopNum
            shopNumProvider.sendShopNumGen(6, purchase.getId(), Const.MARKET_CODE_PURCHASE);
            // delete verify code from redis
            redisTemplate.delete(cachedVerifyCodeKey);
            return JsonResult.SUCCESS;
        } else {
            purchase.setRegStatus(2);
            this.updateById(purchase);
            bizMarketBusiService.remove(new UpdateWrapper<BizMarketBusi>().eq("BusiId", purchase.getId()).eq("BusiType", 6));
            List<BizMarketBusi> bizMarketBusiList = new ArrayList<>();
            Arrays.asList(markCodes.split(",")).forEach(markCode -> {
                BizMarketBusi bizMarketBusi = new BizMarketBusi();
                bizMarketBusi.setBusiType(6);
                bizMarketBusi.setMarkCode(Integer.valueOf(markCode));
                bizMarketBusi.setBusiId(purchase.getId());
                bizMarketBusi.setPaidRent(0);
                bizMarketBusiList.add(bizMarketBusi);
            });
            bizMarketBusiService.saveBatch(bizMarketBusiList);
            List<AnnexBizItem> annexBizItems = new ArrayList<>();
            if (headPicId != null && headPicId != 0L) {
                // 店铺头像
                AnnexBizItem bizItem = new AnnexBizItem();
                bizItem.setAnnexId(Long.valueOf(headPicId));
                bizItem.setBizId(purchase.getId());
                bizItem.setBizType(2);
                annexBizItems.add(bizItem);
            }
            baseClient.enableAnnexStatus(annexBizItems);
            return JsonResult.SUCCESS;
        }
    }

    @Override
    public List<InfoPurchase> getPurchaseForShopNumGen(int limit, int minutes) {
        List<InfoPurchase> resultList = mapper.getPurchaseForShopNumGen(limit, minutes);
        return resultList;
    }

    @Override
    public List<InfoPurchase> getPurchaseByShopNumAndMarkCode(int markCode, Long shopNum) {
        return mapper.getPurchaseByShopNumAndMarkCode(markCode, shopNum);
    }
}
